#!coding:utf-8
# vim: tabstop=4 shiftwidth=4 softtabstop=4

import os
from cvirt.common import config
from cvirt.cnode.storage.driver import LocalPool, NetworkFilesystemPool, ISCSIPool, CifsPool
import logging
from cvirt.manager.models import Storage, Server
from eventlet import tpool
LOG = logging.getLogger(__name__)


def _storage_object(storage):
    LOG.info("storage protocol is %s " % storage.protocol)
    if storage.protocol == 'local':
        return LocalPool(storage)
    if storage.protocol == 'nfs':
        return NetworkFilesystemPool(storage)
    if storage.protocol == 'iscsi':
        return ISCSIPool(storage)
    if storage.protocol == 'cifs':
        return CifsPool(storage)


def get_storage_info(storage):
    sobj = _storage_object(storage)
    if sobj:
        return sobj.list_storage_info()


def attach(storage):
    sobj = _storage_object(storage)
    if sobj:
        sobj.mount()


def detach(storage):
    sobj = _storage_object(storage)
    if sobj:
        LOG.info('detaching storage %s' % storage.name)
        sobj.umount()

def isos(storages):
    def _list_isos():
        isos = []
        for storage in storages:
            if os.path.ismount(storage.mount_point):
                isos.extend([dict(storage=storage.name,name=iso,path=os.path.join(storage.mount_point,iso))
                             for iso in os.listdir(storage.mount_point) if iso.endswith('.iso') or iso.endswith('.ISO')])
        return isos
    #nfs存储失去连接后会阻塞任何读取挂载目录的操作，这里我们使用tpool调用，防止主线程被阻塞
    return tpool.execute(_list_isos)

conf = config.load_settings()

def init_storages():
    LOG.info('init storage...')
    host = Server.objects.get_or_none(ip = conf['cnode.host'],cluster__isnull=False)
    if host:
        for storage in Storage.objects.all_with_deleted().filter(cluster=host.cluster):
            if storage.protocol == 'iscsi' and storage.get_deleted():
                continue
            func = detach if storage.get_deleted() else attach
            LOG.debug("%s storage %s for init" % (func.__name__,storage.name))
            try:
                func(storage)
            except Exception as e:
                LOG.warn("init storage failed,exception is :\n%s" % e )
#
# def discover_target(storage):
#     sobj = _storage_object(storage)
#     if sobj:
#         LOG.info('discover storage target')
#         sobj.discover_target()
#
#
# def discover_target_lun(storage):
#     sobj = _storage_object(storage)
#     if sobj:
#         LOG.info('discover storage target')
#         sobj.discover_target_lun()